#include "core.h"
#include "MapTollGate.h"
#include "Map.h"
#include "xRoomMgr.h"
#include "xTime.h"
#include "JsonEncoding.h"
#include "LogMgr.h"

CTollGate::CTollGate(U64 uGuid)
:xObjBase(CGuidMgr::ENTITY_TOLLGATE, uGuid)
{

}

CTollGate::CTollGate(const CTollGate& src)
:xObjBase(CGuidMgr::ENTITY_TOLLGATE, 0)
{
	TOLL_GATE_ID = src.TOLL_GATE_ID;
	AREA_TOP_X = src.AREA_TOP_X;
	AREA_TOP_Y = src.AREA_TOP_Y;
	AREA_BOTTOM_X = src.AREA_BOTTOM_X;
	AREA_BOTTOM_Y = src.AREA_BOTTOM_Y;
	DIRECTION = src.DIRECTION;
	LEAVE_TIME = src.LEAVE_TIME;
	POS_X = src.POS_X;
	POS_Y = src.POS_Y;
	NEXT_TOLL_GATE = src.NEXT_TOLL_GATE;
	TOLL_GATE_END = src.TOLL_GATE_END;
	BEGIN_TIME = src.BEGIN_TIME;
	MAP_ID = src.MAP_ID;
	ROOM_GUID = src.ROOM_GUID;
	ROOM_ID = src.ROOM_ID;
	HAVE_ACTION_UPDATE  = src.HAVE_ACTION_UPDATE;
	HAVE_AI_UPDATE = src.HAVE_AI_UPDATE;
//	DECLARE_VAR( U32, BT_XML );
//	DECLARE_VAR( U32, BT_POINT );
	STATE = src.STATE;
}
CTollGate::~CTollGate()
{

}

VOID CTollGate::loadFromJson( Json::Value & value )
{
	Json::Value node_value;
	Json::Value node_name;
	for ( Json::Value::iterator it = value.begin(); it != value.end(); it++ )
	{
		node_name = it.key();
		node_value = *it;
		std::string str_name = node_name.asString();
		std::string str_value = node_value.asString();
		if ( str_name == "toll_gate_id" ){
			TOLL_GATE_ID = atol(str_value.c_str());
		}else if ( str_name == "area_top_x" )	{
			AREA_TOP_X = atol(str_value.c_str());
		}else if ( str_name == "area_top_y" )	{
			AREA_TOP_Y = atol(str_value.c_str());
		}else if ( str_name == "area_bottom_x" )	{
			AREA_BOTTOM_X = atol(str_value.c_str());
		}else if ( str_name == "area_bottom_y" )	{
			AREA_BOTTOM_Y = atol(str_value.c_str());
		}else if ( str_name == "direction" )	{
			DIRECTION = atol(str_value.c_str());
		}else if ( str_name == "leave_time" )	{
			LEAVE_TIME = atol(str_value.c_str());
		}else if ( str_name == "pos_x" )	{
			POS_X = atol(str_value.c_str());
		}else if ( str_name == "pos_y" )	{
			POS_Y = atol(str_value.c_str());
		}else if ( str_name == "next_toll_gate" )	{
			NEXT_TOLL_GATE = atol(str_value.c_str());
		}
	}
	LEAVE_TIME *= 1000 ;
}

//-------------------------------------------------------------------------------------
CMapTollGate::CMapTollGate( CMap * map )
: mpMap( map )
, mCurTollGateIDIndex( -1 )
{
	mAllTollGates.reserve(5);
}

CMapTollGate::~CMapTollGate()
{
	mpMap = NULL;
	stopCurTollGate();

	for (ObjVec::iterator it = mAllTollGates.begin(); it != mAllTollGates.end(); ++it)
	{
		xObjBase* pTG = *it;
		delete pTG;
	}
	mAllTollGates.clear();
}

void CMapTollGate::initFromMap(CMap& map)
{
	CMapTollGate * ot = map.getMapTollGate();
	if (ot)
	{
		mTollGateIds.clear();
		ObjVec& oAll = ot->mAllTollGates;
		for ( ObjVec::iterator index = oAll.begin(); index != oAll.end(); index++ )
		{
			CTollGate* pTG = dynamic_cast<CTollGate*>(*index);
			if (pTG)
			{
				CTollGate* pNew = new CTollGate(*pTG);
				if (pNew)
				{
					mAllTollGates.push_back(pNew);
				}
			}
		}
		mTollGateIds = ot->mTollGateIds;
	}
}

BOOL CMapTollGate::initFromJson(Json::Value& initValue)
{
	UINT array_size = initValue.size();
	if (array_size == 0)
	{
		return TRUE;
	}

	mTollGateIds.clear();
	for ( Json::Value::iterator it = initValue.begin(); it != initValue.end(); it++ )
	{
		Json::Value json_toll_gate = *it;
		Json::Value json_type = json_toll_gate[ "toll_gate_type" ];

		UINT type = (UINT)atol( json_type.asString().c_str() );
		
		if (type == 1)
		{
			CTollGate* pNew = new CTollGate();
			if (pNew)
			{
				pNew->loadFromJson(json_toll_gate);
				pNew->setMAP_ID(mpMap->getMapId());
				mAllTollGates.push_back(pNew);
				mTollGateIds.push_back(pNew->getTOLL_GATE_ID());
			}
		}
	}

	return TRUE;
}

BOOL CMapTollGate::loadFile( const std::string &file )
{
	mFile = file;

	UINT map_id = mpMap->getMapId();
	CHAR c_map_id[100];
	sprintf( c_map_id, "%d", map_id );

	Json::Value root;
	CJsonEncoding::load( mFile, root );
	Json::Value json_toll_gates = root[c_map_id];
	UINT array_size = json_toll_gates.size();
	if (array_size == 0)
	{
		json_toll_gates = root["1042"];
		array_size = json_toll_gates.size();
	}
	for ( UINT i = 0; i < array_size; i++ )
	{
		Json::Value json_toll_gate = json_toll_gates[i];

		Json::Value json_type = json_toll_gate[ "toll_gate_type" ];

		UINT type = (UINT)atol( json_type.asString().c_str() );
		if (type == 1)
		{
			CTollGate* pNew = new CTollGate();
			if (pNew)
			{
				pNew->loadFromJson(json_toll_gate);
				pNew->setMAP_ID(mpMap->getMapId());
				mAllTollGates.push_back(pNew);
				mTollGateIds.push_back(pNew->getTOLL_GATE_ID());
			}
		}
	}

	return TRUE;
}

UINT CMapTollGate::startNextTollGate( CRoom * room )
{
	UINT next = mCurTollGateIDIndex + 1;

	return startTollGate(room, next);
}

UINT CMapTollGate::startTollGate( CRoom * room, UINT toll_gate_index )
{
	UINT toll_gate_id = 0;
	CTollGate * toll_gate = NULL;
	
	if (toll_gate_index < mTollGateIds.size())
	{
		toll_gate_id = mTollGateIds[toll_gate_index];
		toll_gate = getTollGate(toll_gate_id);
		
		if (toll_gate)
		{
			toll_gate->setROOM_GUID(room->getGuid());
			toll_gate->setROOM_ID(room->getm_nLevelID());

//			CComActionMgr * com_action_mgr = toll_gate->getCom< CComActionMgr >( ECom::COM_ACTION_MGR );
//			com_action_mgr->pushUpdateAiPacket();

			mCurTollGateIDIndex = toll_gate_index;
			GAMELOGER->info("add tollgate %lld", toll_gate->getGuid());
		}
	}

	if (toll_gate_index == 0)
	{
		mTime = (UINT)xTime::getTime();
		mSendLeftTime = FALSE;
	}

	return toll_gate_id;
}
void CMapTollGate::ResetStartTime()
{
	mTime = (UINT)xTime::getTime();
}
void CMapTollGate::stopCurTollGate()
{
	CTollGate * toll_gate = NULL;

	if (mCurTollGateIDIndex != -1)
	{
		toll_gate = getTollGate(mTollGateIds[mCurTollGateIDIndex]);
		if (toll_gate)
		{
			stopTollGate(toll_gate);
		}
	}
}

void CMapTollGate::stopTollGate( CTollGate * toll_gate)
{
	if (toll_gate)
	{
//		ai_entitys->clearEntity( toll_gate->getAttr( EAttr::GUID )->getUINT() );
		GAMELOGER->info("remove tollgate %lld", toll_gate->getGuid());
	}
}

CTollGate * CMapTollGate::getTollGate()
{
	INT toll_gate_index = mCurTollGateIDIndex;

	if (toll_gate_index == -1)
	{
		toll_gate_index = 0;
	}

	if (toll_gate_index < mTollGateIds.size())
	{
		return getTollGate(mTollGateIds[toll_gate_index]);
	}

	return NULL;
}

BOOL CMapTollGate::isEndTollGate()
{
	return ((mCurTollGateIDIndex+1)==mTollGateIds.size());
}

CTollGate * CMapTollGate::getTollGate( UINT toll_gate_id )
{
	for (ObjVec::iterator it = mAllTollGates.begin(); it != mAllTollGates.end(); ++it)
	{
		CTollGate* pTG = dynamic_cast<CTollGate*>(*it);
		if (pTG && (pTG->getTOLL_GATE_ID() == toll_gate_id))
		{
			return pTG;
		}
	}
	
	return NULL;
}